package com.yjt.javatest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yjt.javatest.dao.CategoryMapper;
import com.yjt.javatest.dao.UserMapper;
import com.yjt.javatest.entity.Category;
import com.yjt.javatest.entity.User;
import com.yjt.javatest.entity.LoginUser;
import com.yjt.javatest.entity.UserType;
import com.yjt.javatest.entity.vo.UserVo;
import com.yjt.javatest.service.UserService;

import com.yjt.javatest.utils.APIResponse;
import com.yjt.javatest.utils.JwtUtil;
import com.yjt.javatest.utils.RedisCache;
import com.yjt.javatest.utils.SecurityUtil;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;


@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    UserMapper userMapper;
    @Resource
    AuthenticationManager authenticationManager;
    @Resource
    RedisCache redisCache;
    @Resource
    CategoryMapper categoryMapper;

    @Override
    public APIResponse register(User user) {
        User user1= userMapper.selectOne(new QueryWrapper<User>().eq("username", user.getUsername()));
        if(!Objects.isNull(user1)) {
            return APIResponse.error("用户名重复");
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user.setName("未命名");
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        if(user.getType().equals(UserType.ADMIN)) {
            return APIResponse.error("不可注册管理员账号");
        }
        userMapper.insert(user);
        if(user.getType().equals(UserType.TEACHER)) {
            Category category = new Category();
            category.setUserId(user.getUserId());
            category.setName("根节点");
            category.setFatherId(0);
            categoryMapper.insert(category);
        }
        return new APIResponse("注册成功");
    }


    @Override
    public APIResponse login(User user, HttpServletResponse response) {
        //AuthenticationManager authenticate进行用户认证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        //如果认证没通过，给出对应的提示
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("登录失败");
        }
        //如果认证通过了，使用userid生成一个jwt jwt存入APIResponse返回
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getUserId().toString();
        String jwt = JwtUtil.createJWT(userId);
        Map<String,String> map = new HashMap<>();
        map.put("token",jwt);
        response.setHeader("token", jwt);
        return new APIResponse(200,"登录成功",map);
    }
    @Override
    public APIResponse logout() {
        try {
            redisCache.deleteObject("login:" + SecurityUtil.getUserId());
            return APIResponse.success("退出登录成功！");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return APIResponse.error("退出登录失败");
    }

    @Override
    public APIResponse getUserInfo() {
        try {
            return APIResponse.success(new UserVo(SecurityUtil.getUser()));
        } catch (Exception e) {
            e.printStackTrace();
            return APIResponse.error("获取用户信息失败");
        }
    }


}
